﻿using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
using SharpDX.Windows;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace DirectXTest.Src
{
    public class DxPlayWindow : IDisposable
    {

        private RenderForm RenderForm;
        private int Width = 400;
        private int Height = 500;
        private SharpDX.Direct3D11.Device _d3DDevice;
        private DeviceContext _d3DDeviceContext;
        private SwapChain _swapChain;
        private RenderTargetView _renderTargetView;

        public DxPlayWindow()
        {
            RenderForm = new RenderForm();
            RenderForm.ClientSize = new Size(Width, Height);
            InitializeDeviceResources();
        }

        public void Run()
        {
            RenderLoop.Run(RenderForm, RenderCallback);
        }

        private void RenderCallback()
        {
            RenderForm.Text = "RenderForm";
            Draw();
        }

        public void Dispose()
        {
            RenderForm?.Dispose();
            _renderTargetView.Dispose();
            _swapChain.Dispose();
            _d3DDevice.Dispose();
            _d3DDeviceContext.Dispose();
            RenderForm?.Dispose();
        }

        private void InitializeDeviceResources()
        {
            ModeDescription backBufferDesc = new ModeDescription(Width, Height, new Rational(60, 1), Format.R8G8B8A8_UNorm);
            SwapChainDescription swapChainDesc = new SwapChainDescription()
            {
                ModeDescription = backBufferDesc,
                SampleDescription = new SampleDescription(1, 0),
                Usage = Usage.RenderTargetOutput,
                BufferCount = 1,
                OutputHandle = RenderForm.Handle,
                IsWindowed = true
            };
            SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, SharpDX.Direct3D11.DeviceCreationFlags.None, swapChainDesc,
                out _d3DDevice, out _swapChain);
            _d3DDeviceContext = _d3DDevice.ImmediateContext;
            using (SharpDX.Direct3D11.Texture2D backBuffer = _swapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0))
            {
                _renderTargetView = new SharpDX.Direct3D11.RenderTargetView(_d3DDevice, backBuffer);
            }
            _d3DDeviceContext.OutputMerger.SetRenderTargets(_renderTargetView);
        }

        private void Draw()
        {
            _d3DDeviceContext.ClearRenderTargetView(_renderTargetView, RandomColorUtils.RandomColor());
            _swapChain.Present(1, PresentFlags.None);
        }

    }
}
